﻿using System;
using System.Linq;
using AbpOne.BackgroundJobs;
using AbpOne.BackgroundJobs.Jobs;
using AbpOne.Domain.Configurations;
using AbpOne.EntityFrameworkCore;
using AbpOne.HttpApi.Hosting.Filters;
using AbpOne.HttpApi.Hosting.Middlewares;
using AbpOne.Swagger;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
using Volo.Abp.Autofac;
using Volo.Abp.Modularity;

namespace AbpOne.HttpApi.Hosting {
    [DependsOn(
        typeof(AbpAspNetCoreMvcModule),
        typeof(AbpAutofacModule),
        typeof(AbpOneHttpApiModule),
        typeof(AbpOneSwaggerModule),
        typeof(AbpOneFrameworkCoreModule),
        typeof(AbpOneBackgroundJobsModule)
    )]
    public class AbpOneHttpApiHostingModule : AbpModule {
        public override void ConfigureServices(ServiceConfigurationContext context) {
            // 身份验证
            context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options => {
                    options.TokenValidationParameters = new TokenValidationParameters {
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,
                        ClockSkew = TimeSpan.FromSeconds(30),
                        ValidateIssuerSigningKey = true,
                        ValidAudience = AppSettings.JWT.Domain,
                        ValidIssuer = AppSettings.JWT.Domain,
                        IssuerSigningKey = new SymmetricSecurityKey(AppSettings.JWT.SecurityKey.GetBytes())
                    };
                });

            // 认证授权
            context.Services.AddAuthorization();

            // Http请求
            context.Services.AddHttpClient();

            // MVC配置
            // Configure<MvcOptions>(options => {
            //     var filterMetadata = options.Filters.FirstOrDefault(x =>
            //         x is ServiceFilterAttribute attribute && attribute.ServiceType.Equals(typeof(AbpExceptionFilter)));
            //
            //     // 移除 AbpExceptionFilter
            //     options.Filters.Remove(filterMetadata);
            //     
            //     // 添加自己实现的 AbpOneExceptionFilter
            //     options.Filters.Add(typeof(AbpOneExceptionFilter));
            // });

            // BackgroundService实现的简单定时任务
            context.Services.AddTransient<IHostedService, HelloWorldJob>();
            
            // 路由规则配置，默认Swagger中的路由是大写的，如果我想转成小写可以使用以下配置代码
            context.Services.AddRouting(options =>
            {
                // 设置URL为小写
                options.LowercaseUrls = true;
                // 在生成的URL后面添加斜杠
                options.AppendTrailingSlash = true;
            });
        }

        public override void OnApplicationInitialization(ApplicationInitializationContext context) {
            var app = context.GetApplicationBuilder();
            var env = context.GetEnvironment();

            // 环境变量，开发环境
            if (env.IsDevelopment()) {
                // 生成异常页面
                app.UseDeveloperExceptionPage();
            }

            // 使用HSTS中间件，该中间件添加了严格传输安全头
            app.UseHsts();

            // 直接使用默认的跨域配置
            app.UseCors();

            // HTTP请求转HTTPS
            app.UseHttpsRedirection();

            // 路由
            app.UseRouting();

            // 异常处理中间件
            app.UseMiddleware<ExceptionHandlerMiddleware>();

            // 身份验证
            app.UseAuthentication();
            // 认证授权
            app.UseAuthorization();

            // 路由映射
            app.UseEndpoints(endpoints => endpoints.MapControllers());
        }
    }
}